package org.tau.workshop2011.widgets

import java.awt.{Component, Dimension}
import org.tau.workshop2011.codegen.{DSLProperty, Property}

/**
 * Created by IntelliJ IDEA.
 * User: Barak
 * Date: 01/12/11
 * Time: 23:34
 * To change this template use File | Settings | File Templates.
 */

object SizingUtils {

  // Big enough to make sure no screen will be in this resolution, at least not
  // while this workshop is relevant. Also small enough to make sure we won't
  // have an overflow soon
  val MAX_DIM_VALUE = + 5*1000*1000
  val MIN_DIM_VALUE = - 5*1000*1000

  case class SizeTriplet(min: Dimension, max: Dimension, pref: Dimension)
    extends Iterable[Dimension] {

    def iterator: Iterator[Dimension] = Iterator(min, max, pref)

    def this() = this (new Dimension, new Dimension, new Dimension)

    def map(func: (Dimension) => Dimension): SizeTriplet = {
      new SizeTriplet(func(min), func(max), func(pref))
    }

    def deepCloneTriplet: SizeTriplet = map(oCopy _)
  }

  def mutateAllComponentSizes(comp: Component, func: (Dimension) => Dimension) {
    val allSizes: SizeTriplet = getMinMaxPrefSizes(comp)
    mutateAllSizes(func, allSizes)
    setMinMaxPrefSizes(comp, allSizes)
  }

  def mutateAllSizes(func: (Dimension) => Dimension, sizes: Traversable[Dimension]) {
    for (size <- sizes)
      size.setSize(func(size))
  }

  def mutateAllSizes(func: (Dimension) => Dimension, sizes: Dimension*) {
    mutateAllSizes(func, sizes)
  }

  def getMinMaxPrefSizes(comp: Component): SizeTriplet = {
    new SizeTriplet(comp.getMinimumSize, comp.getMaximumSize, comp.getPreferredSize)
  }

  def setMinMaxPrefSizes(comp: Component, sizes: SizeTriplet) {
    setMinMaxPrefSizes(comp, min = sizes.min, max = sizes.max, pref = sizes.pref)
  }

  def setMinMaxPrefSizes(comp: Component, min: Dimension, max: Dimension, pref: Dimension) {
    comp.setMinimumSize(min)
    comp.setMaximumSize(max)
    comp.setPreferredSize(pref)
  }

  def mutateUsingTriplet(destMinMaxPref: SizeTriplet, otherMinMaxPref: SizeTriplet, func: (Dimension, Dimension) => Dimension) {
    for ((dimD, dimO) <- destMinMaxPref zip otherMinMaxPref)
      dimD.setSize(func(dimD, dimO))
  }

  def oCopy(d: Dimension): Dimension = new Dimension(d)

  def getMinSize(comp: Component) = comp.getMinimumSize

  def getMaxSize(comp: Component) = comp.getMaximumSize

  def getPrefSize(comp: Component) = comp.getPreferredSize


  case class OrientedNativeWidgetWrapper(nw: NativeWidgetWrapper, mainAxis: Orientation) {
      def getMainSize: Option[DSLProperty[Int]] = {
        if (mainAxis == Orientation.VERTICAL)
          nw.getHeight
        else
          nw.getWidth
      }

      def getSecondSize: Option[DSLProperty[Int]] = {
        if (mainAxis == Orientation.HORIZONTAL)
          nw.getHeight
        else
          nw.getWidth
      }

    def isResizeable: Boolean = getMainSize == None
    def isFillSecondary: Boolean = getSecondSize == None
  }

}

trait HasOrientation {
  def getMainOrientation: Orientation

  def oSetSize(d: Dimension, value: Int) = getMainOrientation.setSize(d, value)

  def oGetSize(d: Dimension): Int = getMainOrientation.getSize(d)

  def oCopySizeNewMain(d: Dimension, newMainValue: Int): Dimension = {
    val result = new Dimension(d)
    oSetSize(result, newMainValue)
    result
  }

  def oCopySizeNewOther(d: Dimension, newOtherValue: Int): Dimension = {
    val result = new Dimension(d)
    getMainOrientation.other.setSize(result, newOtherValue)
    result
  }
}